package lyttest.schedule;

import lombok.extern.slf4j.Slf4j;
import lyttest.common.redisConnect.ClusterRedisConnection;
import lyttest.common.redisConnect.RedisConnection;
import lyttest.common.redisConnect.SentinelRedisConnection;
import lyttest.common.redisConnect.SingleNodeRedisConnection;
import lyttest.uils.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import redis.clients.jedis.HostAndPort;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class RedisKeyQuartzJob implements Job {

    // 静态常量定义不同的 Redis 类型
    private static final String REDIS_CLUSTER = "Cluster";
    private static final String REDIS_SENTINEL = "Sentinel";
    private static final String REDIS_SINGLE = "Single";

    private static final Integer OFFSET = 1;

    @Autowired
    private Environment env;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String redisHost = env.getProperty("spring.redis.host", "");
        int redisPort = env.getProperty("spring.redis.port", Integer.class, 6379);
        String password = env.getProperty("spring.redis.password", "");
        String sentinelNodes = env.getProperty("spring.redis.sentinel.nodes", "");
        String master = env.getProperty("spring.redis.sentinel.master", "");
        //前一天开始时间和结束时间
        // 创建Calendar实例
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date previousDayStartTime = calendar.getTime();

        // 获取前一天的结束时间
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date previousDayEndTime = calendar.getTime();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startTime = sdf.format(previousDayStartTime);
        String endTime = sdf.format(previousDayEndTime);

        // redis类型
        String redisType = checkRedisType(master, sentinelNodes);
        // 创建连接
        RedisConnection redisConnection = createRedisConnection(sentinelNodes, redisType, redisHost, redisPort, password);
        // 定时任务
        try {
            redisKeyQuartz(startTime, endTime, redisConnection);
        } finally {
            redisConnection.close();
        }
//        String userName = (String) context.getJobDetail().getJobDataMap().get("userName");
        System.out.println("观察定时执行时间的间隔");

    }

    private RedisConnection createRedisConnection(String sentinelNodes, String redisType, String redisHost, int redisPort, String redisPassword) {
        switch (redisType) {
            case REDIS_CLUSTER:
                Set<HostAndPort> jedisClusterNodes = Arrays.stream(sentinelNodes.split(","))
                        .map(node -> node.split(":"))
                        .map(parts -> new HostAndPort(parts[0], Integer.parseInt(parts[1])))
                        .collect(Collectors.toSet());
                return new ClusterRedisConnection(jedisClusterNodes);
            case REDIS_SENTINEL:
                Set<String> sentinelSet = new HashSet<>(Arrays.asList(
                        sentinelNodes.split(",")
                ));
                return new SentinelRedisConnection("mymaster", sentinelSet, redisPassword);
            default:
                return new SingleNodeRedisConnection(redisHost, 26379);
        }
    }

    private void redisKeyQuartz(String startTime, String endTime, RedisConnection redisConnection) {

        keys1(startTime, endTime, redisConnection);
        keys2(startTime, endTime, redisConnection);
        //从服务器中获取文件txt,读取文件，获取key
//        List<String> keys = readKeysFromFile(targetFile);

        //存储到key值，并设置value值为"cusc"
//        for (String key : keys) {
//            redisConnection.set(key, "cusc");
//            // 执行GETBIT操作b
//            boolean bit = redisConnection.getBit(key, OFFSET);
//            // 本地测试一下
////            System.out.println(key + ":" + bit);
//        }
        System.out.println("测试完成");
    }

    private String checkRedisType(String masterName, String sentinelNodes) {
        if (StringUtils.isBlank(sentinelNodes)) {
            return REDIS_SINGLE;
        }
        if (StringUtils.isNotBlank(masterName)) {
            return REDIS_SENTINEL;

        } else {
            return REDIS_CLUSTER;
        }
//        Set<String> sentinels = convertToSet(sentinelNodes);
//
//        JedisSentinelPool pool = null;
//        try {
//            pool = new JedisSentinelPool(masterName, sentinels);
//            try (Jedis jedis = pool.getResource()) {
//                // 认证密码
//                if (redisPassword != null && !redisPassword.isEmpty()) {
//                    jedis.auth(redisPassword);
//                }
//                boolean isCluster = false;
//                boolean isSentinel = false;
//
//                try {
//                    if (jedis.clusterInfo() != null) {
//                        isCluster = true;
//                    }
//                } catch (Exception e) {
//                    log.info("Cluster Info check failed");
//                }
//
//                if (!isCluster) {
//                    try {
//                        if (!jedis.sentinelMasters().isEmpty()) {
//                            isSentinel = true;
//                        }
//                    } catch (Exception e) {
//                        log.info("Sentinel Masters check failed", e);
//                    }
//                }
//
//                if (isCluster) {
//                    return REDIS_CLUSTER;
//                } else if (isSentinel) {
//                    return REDIS_SENTINEL;
//                } else {
//                    return REDIS_SINGLE;
//                }
//                try {
//                    if (jedis.clusterInfo() != null) {
//                        return REDIS_CLUSTER;
//                    }
//                } catch (Exception e) {
//                    log.info("Cluster Info check failed");
//                    return REDIS_SENTINEL;
//                }
//                return REDIS_SENTINEL;
//            }
//        } finally {
//            if (pool != null) {
//                pool.close();
//            }
//        }
    }

    private static List<String> readKeysFromFile(String targetFile) {
        List<String> keys = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(targetFile))) {
            String line;
            while ((line = br.readLine()) != null) {
                keys.add(line.trim());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return keys;
    }

    public static Set<String> convertToSet(String nodes) {
        Set<String> sentinels = new HashSet<>();

        // 分割字符串
        String[] nodeArray = nodes.split(",\\s*");

        // 将每个节点地址添加到Set中
        for (String node : nodeArray) {
            sentinels.add(node.trim());
        }

        return sentinels;
    }

    public static void keys1(String start, String end, RedisConnection redisConnection) {
        String startTimeStr = start;
        String endTimeStr = end;

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date startDate = dateFormat.parse(startTimeStr);
            Date endDate = dateFormat.parse(endTimeStr);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);

            while (calendar.getTime().before(endDate) || calendar.getTime().equals(endDate)) {
                // Get timestamp for current calendar time
                long timestamp = calendar.getTimeInMillis();
                for (int i = 0; i < 4; i++) {
                    redisConnection.set("CT:CONSTRUCTION:" + timestamp + ":" + i + "\r\n", "cusc");
                    redisConnection.getBit("CT:CONSTRUCTION:" + timestamp + ":" + i + "\r\n", OFFSET);
                    if (i > 0) {
                        redisConnection.set("CT:CONSTRUCTION:" + timestamp + ":-" + i + "\r\n", "cusc");
                        redisConnection.getBit("CT:CONSTRUCTION:" + timestamp + ":-" + i + "\r\n", OFFSET);
                    }
                }
                calendar.add(Calendar.MINUTE, 30);
            }
            System.out.println("生成key1，并gitbit key 1");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void keys2(String start, String end, RedisConnection redisConnection) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date startDate = dateFormat.parse(start);
            Date endDate = dateFormat.parse(end);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            while (calendar.getTime().before(endDate) || calendar.getTime().equals(endDate)) {
                // Get timestamp for current calendar time
                String formatDate = dateFormat.format(calendar.getTime());
                for (int i = 0; i <= 24; i++) {
                    for (int j = 0; j <= 8; j++) {
                        redisConnection.set("CT:CONSTRUCTION:UNREPEATEDBLOOM:" + formatDate + ":" + i + ":" + j + "\r\n", "cusc");
                        redisConnection.getBit("CT:CONSTRUCTION:UNREPEATEDBLOOM:" + formatDate + ":" + i + ":" + j + "\r\n", OFFSET);
                        if (j > 0) {
                            redisConnection.set(
                                    "CT:CONSTRUCTION:UNREPEATEDBLOOM:" + formatDate + ":" + i + ":-" + j + "\r\n", "cusc");
                            redisConnection.getBit(
                                    "CT:CONSTRUCTION:UNREPEATEDBLOOM:" + formatDate + ":" + i + ":-" + j + "\r\n", OFFSET);

                        }
                    }
                }
                calendar.add(Calendar.DATE, 1);
            }
            System.out.println("生成key2,并gitbit key 1");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}